
package com.honey.compilation.xml;

import java.util.ArrayList;
import java.util.List;

import com.honey.core.builder.CharacterBuilder;
import com.honey.core.builder.CharacterBuilderFactory;
import com.honey.core.compiler.IndentSpace;
import com.honey.core.utils.StringUtility;

/**
 * xml 节点
 * @author Administrator
 *
 */
public class XmlElement extends AbstractElement {
	
	/** xml节点属性 */
    private List<Attribute> attributes;

    /** xml的子节点*/
    private List<AbstractElement> elements;

    /** 节点名称 */
    private String name;
    
    private CommentsElement docs;
    
    /**
     * 构造函数
     * @param name 节点名称
     */
    public XmlElement(String name) {
        super();
        attributes = new ArrayList<Attribute>();
        elements = new ArrayList<AbstractElement>();
        docs = new CommentsElement();
        this.name = name;
    }
    
    /**
     * 构造函数
     * @param name 节点名称
     */
    public XmlElement(XmlElement parent ,String name) {
        super();
        attributes = new ArrayList<Attribute>();
        elements = new ArrayList<AbstractElement>();
        docs = new CommentsElement();
        this.name = name;
        parent.addElement(this);
    }
    
    /**
     * 获取xml节点所有的属性
     * @return
     */
    public List<Attribute> getAttributes() {
        return attributes;
    }
    
    /**
     * 根据属性名称获取一个属性节点
     * @param attributeName
     * @return
     */
    public Attribute getAttribute(String attributeName) {
    	Attribute answer = null;
    	for(Attribute att : attributes){
    		if( att.getName() .equals(attributeName)){
    			answer = att;
    			break ;
    		} 
    	}
    	return answer;
    }
    
    /**
     * 添加xml节点属性
     * @param attributes xml节点属性
     */
    public XmlElement addAttribute(Attribute ...attributes) {
        for(Attribute attribute : attributes){
        	if(attribute != null) this.attributes.add(attribute);
        }
        return this;
    }
    
    /**
     * 添加xml节点属性
     * @param name 属性名称
     * @param value 属性值
     */
    public XmlElement addAttribute(String name , String value) {
    	if(StringUtility.stringHasValue(name) && value!= null ){
    		this.attributes.add(new Attribute(name,value));
    	}
    	return this;
    }

    /**
     * 
     * 获取xml子节点
     * @return
     */
    public List<AbstractElement> getElements() {
        return elements;
    }
    
    /**
     * 添加xml节点
     * @param elementName 节点名称
     * @param text 节点内容
     */
    public XmlElement addElement(String elementName, String text) {
    	XmlElement xml = new XmlElement(elementName);
    	xml.addTextElement(text);
    	elements.add(xml);
    	return this;
    }
    
    /**
     * 添加xml节点
     * @param elements 子节点
     */
    public XmlElement addElement(AbstractElement ...elements) {
    	for(AbstractElement element : elements){
        	if(element != null) this.elements.add(element);
        }
    	return this;
    }

    /**
     * 添加字符字符串
     * @param str 字符串
     */
    public XmlElement addTextElement(String ...str) {
    	TextElement element = new TextElement(str);
        elements.add(element);
        return this;
    }

    /**
     * 添加新行
     */
    public XmlElement addNewLine() {
    	TextElement element = new TextElement(StringUtility.EMPTY);
        elements.add(element);
        return this;
    }
    
    /**
     * 添加xml的CDATA内容
     * @param str CDATA字符串
     */
    public XmlElement addCDATA(String ...str) {
    	CDATAElement element = new CDATAElement(str);
        elements.add(element);
        return this;
    }

    /**
     * 添加xml注释
     * @param str 注释内容
     */
    public XmlElement addComments(String ...str) {
    	CommentsElement element = new CommentsElement(str);
        elements.add(element);
        return this;
    }

    /**
     * 获取节点名称
     * @return
     */
    public String getName() {
        return name;
    }
    
    /**
     * 添加节点注释
     * @param docs
     */
    public XmlElement addXmlDoc( String ...docs ){
    	for(String doc : docs ){
    		if(doc != null)
    			this.docs.addContent(doc);
    	}
    	return this;
    }
    
    /**
     * 设定xml节点名称
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }
    
    @Override
	public boolean isEmpyt() {
		
		return false ;
	}
    
    @Override
    public CharacterBuilder compiledContent(int indentLevel) {
    	CharacterBuilder answer = CharacterBuilderFactory.createC16StringBuilder();
    	if( !StringUtility.stringHasValue(name)){
    		return answer;
    	}
    	if( !docs.isEmpyt() ){
    		answer.append(docs.compiledContent(indentLevel, true));
    		
    	}
        IndentSpace.spaceIndent(answer, indentLevel);
        answer.append('<')
        .append(name);
        int lineLength = 120,i = 1;
        
        for (Attribute att : attributes) {
            answer.append(' ')
            .append(att.compiledContent());
            if(answer.length() > lineLength ){
            	i++;
            	IndentSpace.newSpace(answer, indentLevel+1);
            	lineLength *= i;
            }
        }
        if (elements.size() > 0) {
            answer.append(">");
            for (AbstractElement element : elements) {
            	if( !element.isEmpyt()){
            		IndentSpace.newLine(answer);
            		answer.append(element.compiledContent( indentLevel + 1 ));
            	}
            }
        	IndentSpace.newSpace(answer, indentLevel);
            answer.append("</")
            .append(name)
            .append('>');
        } else {
            answer.append(" />");
        }
        return answer;
    }
}
